from deepface import DeepFace
import cv2

#人臉識別模型
models = [
  "VGG-Face", 
  "Facenet", 
  "Facenet512", 
  "OpenFace", 
  "DeepFace", 
  "DeepID", 
  "ArcFace", 
  "Dlib", 
  "SFace",
  "GhostFaceNet",
]

#人臉向量相似度計算
metrics = ["cosine","euclidean","euclidean_l2"]

#人臉檢測模型
backends = [
   'opencv',
   'ssd',
   'dlib',
   'mtcnn', 
   'fastmtcnn',
   'mediapipe',
   'yolov8',
   'yunet',
   'centerface',  
]

#人臉是否對齊
alignment_modes = [True ,False]

#face verification
def face_Verifi(img_path1,img_path2):
    print("face verification....")
    objs = DeepFace.verify(
      img1_path = img_path1,
      img2_path = img_path2,
      model_name = models[1],
      distance_metric = metrics[1],
      detector_backend = backends[0],
      align = alignment_modes[0],
    )
    print("face verifi results: \n", objs)
    print("**********************************")

#face find
def face_Find(image_path):
    print("face find...")
    objs = DeepFace.find(
      img_path = image_path,
      db_path = "./my_db", 
      model_name = models[1],
      distance_metric = metrics[2],
      detector_backend = backends[1],
      align = alignment_modes[0],
    )
    print("face find: \n", objs)
    print("**********************************")

#face embeddings
def face_Embeddings(image_path):
    print("face embedding...")
    objs = DeepFace.represent(
      img_path = image_path,
      model_name = models[2],
      detector_backend = backends[3],
      align = alignment_modes[0],
    )
    for obj in objs:
        embedding = obj["embedding"]
        print("embedding dim", len(embedding))
    #print("face embedding: \n",objs)
    print("**********************************")

#face analysis
def face_Analysis(image_path):
    print("face analysis...")
    objs = DeepFace.analyze(
      img_path = image_path,
      actions = ['age','gender','race','emotion'],
      detector_backend = backends[3],
      align = alignment_modes[0],
    )
    print("face analysis: \n",objs)
    print("**********************************")

#face detection and alignment
def face_Extract(image_path):
    print("face extract...")
    img = cv2.imread(image_path)
    objs = DeepFace.extract_faces(
      img_path = image_path,
      detector_backend = backends[7],
      align = alignment_modes[0],                                                                            
    )
    for obj in objs:
        facial_area = obj["facial_area"]
        print("facial:",facial_area)
        x = int(facial_area["x"])
        y = int(facial_area["y"])
        w = int(facial_area["w"])
        h = int(facial_area["h"])
        cv2.rectangle(img,(x,y),(x+w,y+h),(127,127,255),3)
        cv2.circle(img,tuple(facial_area["left_eye"]),10,(0,0,255),-1)
        cv2.circle(img,tuple(facial_area["right_eye"]),10,(0,0,255),-1)
        confidence = obj["confidence"]
        print("condidence:",confidence)
        cv2.putText(img,"conf: " + str(confidence),(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)
        #save
        cv2.imwrite("face_extract.jpg", img)

    #print("face extract: \n",objs)
    print("***********************************")


if __name__=='__main__':
    path1 = "./dataset/img1.jpg"
    path2 = "./dataset/img2.jpg"
    #face_Extract(path1)
    #face_Verifi(path1, path2)
    #face_Find(path1)
    #face_Embeddings(path1)
    face_Analysis(path1)
